<template>
    <!-- 参考网址：https://blog.csdn.net/sleepwalker_1992/article/details/87894588 -->
    <div>
      <!-- <div class="mask" v-show="isShowSelect" @click="isShowSelect = !isShowSelect"></div> -->
      <el-popover
        v-model="isShowSelect"
        placement="bottom-start"
        :width="width"
        trigger="manual"
        @hide="popoverHide"
      >
        <!-- :show-checkbox="multiple" 在el-tree显示复选框 -->
        <el-tree
          ref="tree"
          class="common-tree"
          :style="style"
          :data="data"
          :props="defaultProps"
          :node-key="nodeKey"
          :check-strictly="checkStrictly" 
          :expand-on-click-node="false"
          :default-checked-keys="defaultCheckedKeys"
          :highlight-current="true"
          @node-click="handleNodeClick"
          @check-change="handleCheckChange"
        />
        <el-select
          slot="reference"
          ref="select"
          v-model="selectedData"
          :style="selectStyle"
          :multiple="multiple"
          class="tree-select"
          @click.native="isShowSelect = !isShowSelect"
        >
          <!-- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option> -->
        </el-select>
      </el-popover>
    </div>
  </template>
  
  <script>
  export default {
    name: 'TreeSelect',
    props: {
      // 树结构数据
      data: {
        type: Array,
        default() {
          return []
        }
      },
      defaultProps: {
        type: Object,
        default() {
          return {}
        }
      },
      // 配置是否可多选
      multiple: {
        type: Boolean,
        default() {
          return false
        }
      },
      nodeKey: {
        type: String,
        default() {
          return 'id'
        }
      },
      // 显示复选框情况下，是否严格遵循父子不互相关联
      checkStrictly: {
        type: Boolean,
        default() {
          return false
        }
      },
      // 默认选中的节点key数组
      checkedKeys: {
        type: Array,
        default() {
          return []
        }
      },
      width: {
        type: Number,
        default() {
          return 450
        }
      },
      height: {
        type: Number,
        default() {
          return 200
        }
      }
    },
    data() {
      return {
        defaultCheckedKeys: [],
        isShowSelect: false, // 是否显示树状选择器
        options: [],
        selectedData: '', // 选中的节点
        style: 'width:' + this.width + 'px;' + 'height:' + this.height + 'px;',
        selectStyle: 'width:' + (this.width + 24) + 'px;',
        checkedIds: [],
        checkedData: []
      }
    },
    watch: {
      isShowSelect(val) {
        // 隐藏select自带的下拉框
        this.$refs.select.blur()
      }
    },
    mounted() {
      if (this.checkedKeys.length > 0) { // 选中传进来的节点
        var item = this.checkedKeys[0]
        this.$nextTick(() => {
          // 将从Rights.vue中传递过来的checkedKeys值赋值给defaultCheckdKeys，即让指定的权限节点被选中
          this.$refs.tree.setCurrentKey(item)
          var node = this.$refs.tree.getNode(item)
          this.selectedData = node.label
        })
      } else { // 清空选中 this.selectedData = "";
        this.$refs.tree.setCurrentKey(null)
      }
  
      this.$nextTick(function() {
        // 在子组件中定义使用this.$on绑定事件监听，此处绑定名为updateCheckedKey组件的监听实现当父组件使用$emit调用当前这个子组件的updateCheckedKey事件时，就会执行此事件中的代码，实现选中某个树形节点
        this.$on('updateCheckedKey', function() {
          // 通过权限编号checkedKeys从树形控件对象中获取所对应的节点对象node,再把这个节点对象node的label值在下拉框中显示
          if (this.checkedKeys.length > 0) { // 选中传进来的节点
            var item = this.checkedKeys[0]
            this.$nextTick(() => {
              // 将从Rights.vue中传递过来的checkedKeys值赋值给defaultCheckdKeys，即让指定的权限节点被选中
              this.$refs.tree.setCurrentKey(item)
              var node = this.$refs.tree.getNode(item)
              this.selectedData = node.label
            })
          } else { // 清空选中 this.selectedData = "";
            this.$refs.tree.setCurrentKey(null)
          }
        })
      })
    },
    methods: {
      popoverHide() {
        if (this.multiple) {
          this.checkedIds = this.$refs.tree.getCheckedKeys() // 所有被选中的节点的 key 所组成的数组数据
          this.checkedData = this.$refs.tree.getCheckedNodes() // 所有被选中的节点所组成的数组数据
        } else {
          this.checkedIds = this.$refs.tree.getCurrentKey()
          this.checkedData = this.$refs.tree.getCurrentNode()
        }
        this.$emit('popoverHide', this.checkedIds, this.checkedData)
      },
      // 节点被点击时的回调,返回被点击的节点数据
      handleNodeClick(data, node) {
        if (!this.multiple) {
          const tmpMap = {}
          tmpMap.value = node.key
          tmpMap.label = node.label
          this.options = []
          this.options.push(tmpMap)
          this.selectedData = node.label
          this.isShowSelect = !this.isShowSelect
        }
      },
      // 节点选中状态发生变化时的回调
      handleCheckChange() {
        var checkedKeys = this.$refs.tree.getCheckedKeys() // 所有被选中的节点的 key 所组成的数组数据
        this.options = checkedKeys.map((item) => {
          var node = this.$refs.tree.getNode(item) // 所有被选中的节点对应的node
          const tmpMap = {}
          tmpMap.value = node.key
          tmpMap.label = node.label
          return tmpMap
        })
        this.selectedData = this.options.map((item) => {
          return item.label
        })
      }
    }
  }
  </script>
  <style scoped>
    .mask {
      width: 100%;
      height: 100%;
      position: fixed;
      top: 0;
      left: 0;
      opacity: 0;
    }
    .common-tree {
      overflow: auto;
    }
  
    .tree-select .el-select__tags .el-tag .el-tag__close {
      display: none;
    }
    .tree-select .el-select__tags .el-tag .el-icon-close {
      display: none;
    }
  </style>
  